package edu.fau.scanny.r;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.REngineException;
import org.rosuda.REngine.Rserve.RConnection;

public class RBioconductorUtils {

	public enum LogLinear {
		LOG, LINEAR
	}

	public enum QuantileNormalize {
		YES, NO
	}

//	needs simpleaffy and multicore
	public static void readAffy(RConnection rc, String sampleName, List<String> celFiles) throws REngineException, REXPMismatchException {
		
//		parallel(rc, String.format("ReadAffy(\"%s\")", StringUtils.join(celFiles, "\",\"")), sampleName);
		String readAffy = String.format("%s=ReadAffy(\"%s\")", sampleName, StringUtils.join(celFiles, "\",\""));
		RUtils.runRExp(rc, readAffy);
//		System.out.println(readAffy);
//		rc.parseAndEval(readAffy);
	}
	
	public static void parallel(RConnection rc, String function, String assignTo) throws REngineException, REXPMismatchException{
		String para = "q.para";
		RUtils.runRExp(rc, String.format("%s=parallel(%s)", para, function));
		String coll = "col.para";
		RUtils.runRExp(rc, String.format("%s=collect(list(%s))", coll, para));
		RUtils.runRExp(rc, String.format("%s=%s[[1]]", assignTo, coll));
		RUtils.runRExp(rc, String.format("rm(%s)",coll));
	}

	public static File normalize(RConnection rc, String normDataVarName, String normalizeFunction) throws REngineException, REXPMismatchException,
			IOException {
		File normFile = File.createTempFile("norm_", ".txt");
		String normFileName = normFile.getAbsolutePath().replace("\\", "/");
		System.out.println(normDataVarName + "=" + normalizeFunction);
		rc.parseAndEval(normDataVarName + "=" + normalizeFunction);
		String writeExp = String.format("write.exprs(%s, file=\"%s\")", normDataVarName, normFileName);
		System.out.println(writeExp);
		rc.parseAndEval(writeExp);
		System.out.println(String.format("exprs(%s)->%s", normDataVarName, normDataVarName));
		rc.parseAndEval(String.format("exprs(%s)->%s", normDataVarName, normDataVarName));
		return normFile;
	}

	public static void preprocessCoreLibrary(RConnection rc) throws REngineException, REXPMismatchException {
		RUtils.loadLibrary(rc, "preprocessCore");
	}

	// mas5(samples)->>normData
	// exprs(normData)->>normData
	// needs multicore
	public static void mas5(RConnection rc, String samplesVar, String normDataVar) throws REngineException, REXPMismatchException {
//		parallel(rc , String.format("mas5(%s)", samplesVar), normDataVar);
		String mas5 = String.format("mas5(%s)->%s", samplesVar, normDataVar);
		RUtils.runRExp(rc, mas5);
		exprs(rc, normDataVar, normDataVar);
	}

	// rma(samples)->>normData
	// exprs(normData)->normData
	// normData<-2^normData
	// needs multicore
	public static void rma(RConnection rc, String samplesVar, String normDataVar) throws REngineException, REXPMismatchException {
		String rma = String.format("rma(%s)->%s", samplesVar, normDataVar);
		RUtils.runRExp(rc, rma);
//		parallel(rc , String.format("rma(%s)", samplesVar), normDataVar);
		exprs(rc, normDataVar, normDataVar);
	}

	// normData<<-justPlier(samples,normalize=FALSE)
	// normData<<-exprs(normData)
	// normData2<-2^normData2
	// needs multicore
	public static void plier(RConnection rc, String samplesVar, String normDataVar) throws REngineException, REXPMismatchException {
		RUtils.loadLibrary(rc, "plier");
		String plier = String.format("%s<-justPlier(%s,normalize=FALSE)", normDataVar, samplesVar);
		RUtils.runRExp(rc, plier);
		exprs(rc, normDataVar, normDataVar);
	}

	// Bolstad, B. M., Irizarry R. A., Astrand, M, and Speed, T. P. (2003) A
	// Comparison of Normalization Methods for High Density Oligonucleotide
	// Array Data Based on Bias and Variance. Bioinformatics 19(2) ,pp 185-193.
	// http://bmbolstad.com/misc/normalize/normalize.html
	// normalize.quantiles(normData)->normData2
	// colnames(normData2)<-colnames(normData)
	// rownames(normData2)<-rownames(normData)
	// normData<<-normData2
	public static void quantileNormalize(RConnection rc, String normDataVar) throws REngineException, REXPMismatchException {
		String normData2 = "normData2";
		String quantileNormalize = String.format("normalize.quantiles(%s)->%s", normDataVar, normData2);
		RUtils.runRExp(rc, quantileNormalize);
		RUtils.colNames(rc, normDataVar, normData2);
		RUtils.assignRowNames(rc, normDataVar, normData2);
		String reassign = String.format("%s<-%s", normDataVar, normData2);
		RUtils.runRExp(rc, reassign);
	}

	public static void exprs(RConnection rc, String tableVar, String outTableVar) throws REngineException, REXPMismatchException {
		String exprs = String.format("exprs(%s)->%s", tableVar, outTableVar);
		RUtils.runRExp(rc, exprs);
	}

	public static void mas5calls(RConnection rc, String samplesVar, String colNamesVar, String outVar) throws REngineException, REXPMismatchException {
		String mas5calls = String.format("mas5calls(%s[,%s],alpha1=0.05,alpha2=0.065)->%s", samplesVar, colNamesVar, outVar);
		RUtils.runRExp(rc, mas5calls);
	}
}
